/**
 * @Author       : Hejh(3010733382@qq.com)
 * @Version      : V1.0
 * @Date         : 2024-02-23 10:50:17
 * @Description  : 系统概览信息获取
 */
const { Op } = require('sequelize')
const parser = require('ua-parser-js')
const moment = require('moment')
const { SystemLog } = require('@/framework/mongoose')
const R = require('@/models/Response')
const { User, Source } = require('@/models/model')
const WpFile = require('@/models/fileModel')
const { fileTypeList } = require('@/constants/fileTypes')
const Mysequelize = require('../models')
const { LOG_TYPE } = require('@/constants/log')

/**
 * 列表查询系统概览接口
 * @param {*} ctx
 * @returns
 */
module.exports.listSystemOverview = async (ctx) => {
  /* 
    系统概览信息
    1. 总用户数
    2. 激活/禁用用户数
    3. 今日登录用户数
    4. 请求次数
    5. 请求的用户数
  */

  const overview = {
    userCount: 0,
    activeUser: 0,
    inActiveUser: 0,
    reqCount: 0,
    reqUser: 0,
    loginUser: 0,
    sourceCount: 0,
    sourceNewCount: 0,
    sourceSize: 0,
    uploadCnt: 0,
    downloadCnt: 0,
    delCnt: 0,
    editCnt: 0
  }

  const users = await User.findAll({
    attributes: ['id', 'isActive']
  })

  overview.userCount = users.length
  overview.activeUser = users.filter((item) => item.isActive === 1).length
  overview.inActiveUser = overview.userCount - overview.activeUser

  // 获取当前日期

  // 获取今天的起始时间（零点）
  const startOfToday = moment().startOf('day')

  // 获取今天的结束时间（23:59:59）
  const endOfToday = moment().endOf('day')

  const logs = await SystemLog.find({
    type: LOG_TYPE.HTTP_LOG,
    createTime: {
      $gt: startOfToday,
      $lt: endOfToday
    }
  })

  const loginLogs = await SystemLog.find({
    type: LOG_TYPE.USER_LOGIN,
    createTime: {
      $gt: startOfToday,
      $lt: endOfToday
    }
  })

  overview.reqCount = logs.length
  overview.reqUser = [
    ...new Set(logs.map((item) => item.userId).filter((v) => !!v))
  ].length

  overview.loginUser = [
    ...new Set(loginLogs.map((item) => item.userId).filter((v) => !!v))
  ].length

  // 查询总文件数量
  overview.sourceCount = await Source.count({
    where: {
      isDir: 0
    }
  })

  // 查询今日新增文件数量
  overview.sourceNewCount = await Source.count({
    where: {
      isDir: 0,
      createTime: {
        [Op.gt]: startOfToday,
        [Op.lt]: endOfToday
      }
    }
  })

  // 查询空间使用容量
  const totalInfo = await WpFile.findAll({
    attributes: [[Mysequelize.fn('sum', Mysequelize.col('size')), 'totalSize']]
  })

  // 查询文件上传
  overview.uploadCnt = await SystemLog.countDocuments({
    type: LOG_TYPE.SOURCE_UPLOAD,
    createTime: {
      $gt: startOfToday,
      $lt: endOfToday
    }
  })

  // 查询文件下载
  overview.downloadCnt = await SystemLog.countDocuments({
    type: {
      $in: [LOG_TYPE.SOURCE_DOWNLOAD, LOG_TYPE.SOURCE_DIR_DOWNLOAD]
    },
    createTime: {
      $gt: startOfToday,
      $lt: endOfToday
    }
  })

  // 查询文件编辑
  overview.editCnt = await SystemLog.countDocuments({
    type: {
      $in: [
        LOG_TYPE.SOURCE_EDIT,
        LOG_TYPE.SOURCE_MAKEIDR,
        LOG_TYPE.SOURCE_COPY,
        LOG_TYPE.SOURCE_MOVE,
        LOG_TYPE.SOURCE_RENAME,
        LOG_TYPE.SOURCE_INNER_SHARE,
        LOG_TYPE.SOURCE_EXTEND_SHARE
      ]
    },
    createTime: {
      $gt: startOfToday,
      $lt: endOfToday
    }
  })

  // 查询文件删除
  overview.delCnt = await SystemLog.countDocuments({
    type: {
      $in: [LOG_TYPE.SOURCE_TOBIN, LOG_TYPE.SOURCE_DELETE]
    },
    createTime: {
      $gt: startOfToday,
      $lt: endOfToday
    }
  })

  overview.sourceSize = totalInfo[0].dataValues.totalSize

  ctx.body = R.success(overview)
}

/**
 * @author: Hejh(3010733382@qq.com)
 * @description: 查询用户或者部门空间使用的接口
 * @param {*} ctx
 */
module.exports.listSpaceChart = async (ctx) => {
  const { targetId, targetType } = ctx.newQuery

  // 查询用户的空间文件个数，按type进行归类
  const userCharts = await Source.findAll({
    where: {
      isDir: 0,
      targetType,
      targetId: BigInt(targetId)
    },
    include: [
      {
        model: WpFile,
        required: false,
        as: 'file',
        attributes: []
      }
    ],
    attributes: [
      'type',
      [Mysequelize.fn('COUNT', 'id'), 'count'],
      [Mysequelize.fn('SUM', Mysequelize.col('file.size')), 'totalSize']
    ],
    // 查询 type 字段和每个类型的数量
    group: ['type']
  })

  // 根据type进行汇总
  const res = fileTypeList.map((item) => {
    const obj = {
      name: item.title,
      total: 0,
      totalSize: 0
    }
    userCharts.forEach((v) => {
      if (item.type.includes(v.dataValues.type)) {
        obj.total += +v.dataValues.count || 0
        obj.totalSize += +v.dataValues.totalSize || 0
      }
    })

    return obj
  })

  ctx.body = R.success({
    items: res
  })
}

/**
 * 根据传入的时间生成日期范围
 * @param {*} time
 * @param {*} type
 */
module.exports.generTimeRange = (time, type) => {
  const givenDate = new Date(time)
  if (type === 0) {
    const firstDayOfWeek = new Date(givenDate)
    firstDayOfWeek.setDate(givenDate.getDate() - givenDate.getDay() + 1) // 将日期调整到周一

    // 计算该周的开始日期和结束日期
    const startOfWeek = new Date(firstDayOfWeek)
    const endOfWeek = new Date(firstDayOfWeek)
    endOfWeek.setDate(firstDayOfWeek.getDate() + 6) // 将日期调整到周日

    return {
      startTime: startOfWeek,
      endTime: endOfWeek
    }
  } else if (type === 2) {
    // 获取月范围
    // 找到该月的第一天
    const firstDayOfMonth = new Date(
      givenDate.getFullYear(),
      givenDate.getMonth(),
      1
    )

    // 找到该月的最后一天
    const lastDayOfMonth = new Date(
      givenDate.getFullYear(),
      givenDate.getMonth() + 1,
      0
    )

    return {
      startTime: firstDayOfMonth,
      endTime: lastDayOfMonth
    }
  } else if (type === 3) {
  }
}

/**
 * 额外的方法，获取截至到当天的总用户数
 */
module.exports.getUserTotalAtToday = async (time) => {
  const date = new Date(time)
  const endTime = new Date(
    date.getFullYear(),
    date.getMonth(),
    date.getDate(),
    23,
    59,
    59
  )

  // 查询出用户总数
  const cnt = await User.count({
    where: {
      createTime: {
        [Op.lt]: endTime
      }
    }
  })

  return cnt
}

/**
 * 额外的方法，获取到startTime到endTime范围内每一天的最后一秒
 */

module.exports.getLastOfDay = (startTime, endTime) => {
  const startDate = new Date(startTime)
  const endDate = new Date(endTime)

  // 循环遍历日期范围内的每一天，并获取每一天的最后一秒的时刻
  let currentDate = new Date(startDate)

  while (currentDate <= endDate) {
    const lastSecondOfDay = new Date(
      currentDate.getFullYear(),
      currentDate.getMonth(),
      currentDate.getDate(),
      23,
      59,
      59
    )
    console.log(
      `${currentDate.toDateString()} 的最后一秒的时刻：${lastSecondOfDay.toTimeString()}`
    )
    currentDate.setDate(currentDate.getDate() + 1) // 将日期设为下一天
  }
}

/**
 * @author: Hejh(3010733382@qq.com)
 * @description: 列表获取用户数据，年，月，周
 * @param {*} ctx
 */
module.exports.listUserData = async (ctx) => {
  // 传入一个自定义日期和类型，周，月，年，实现分组
  const { time, type } = ctx.newQuery

  // 只需要查询出time所在那一年的信息，也就是按月分组，开始和结束时间为年的第一天和最后一天
  if (type === 2) {
  }

  // 根据传入的日期生成周范围,月范围
  const timeRange = this.generTimeRange(time, type)
  if (type === 0) {
    const users = await User.findAll({
      where: {
        createTime: {
          [Op.between]: [timeRange.startTime, timeRange.endTime]
        }
      },
      attributes: [
        [Mysequelize.fn('DATE', Mysequelize.col('create_time')), 'day'],
        [Mysequelize.fn('COUNT', Mysequelize.col('*')), 'count']
      ],
      group: [Mysequelize.fn('DATE', Mysequelize.col('create_time'))]
    })

    ctx.body = R.success({
      items: users
    })
    // 按周
  } else if (type === 1) {
    // 按月分组
    const users = await Source.findAll({
      where: {
        createTime: {
          [Op.between]: [timeRange.startTime, timeRange.endTime]
        }
      },
      attributes: [
        [Mysequelize.fn('DATE', Mysequelize.col('create_time')), 'day'],
        [Mysequelize.fn('COUNT', Mysequelize.col('*')), 'count']
      ],
      group: [Mysequelize.fn('DATE', Mysequelize.col('create_time'))]
    })

    ctx.body = R.success({
      items: users
    })
  } else if (type === 2) {
    // 按年分组
  }

  // 总数的计算，create_time小于某一天
  // 新增的计算，按天分组，按月分组
  // 登录的计算，按天分组，按月分组

  // const sources = await Source.findAll({
  //   where: {
  //     createTime: {
  //       [Op.gt]: '2024-3-16'
  //     }
  //   },
  //   attributes: [
  //     [Mysequelize.fn('DATE', Mysequelize.col('create_time')), 'day'],
  //     [Mysequelize.fn('COUNT', Mysequelize.col('*')), 'count']
  //   ],
  //   group: [Mysequelize.fn('DATE', Mysequelize.col('create_time'))]
  // })
}
